/*
 * Copyright (c) 2009 by unreserved.org.
 * All rights reserved.
 */

package org.unreserved.ladderplot;

import org.apache.log4j.Logger;

/**
 * Renders a LadderPlot Model as text.
 */
public class ModelTextRenderer implements TextRenderer, ModelVisitor {
    private static final Logger logger = Logger.getLogger(ModelTextRenderer.class);
    
    protected Model model;
    protected Player[] players;
    protected TextCanvas canvas;
    protected boolean drawPlayerLines = false;
    
    public ModelTextRenderer(Model model) {
        this.model = model;
        canvas = new TextCanvas(this);
        players = model.getPlayers();
    }
    
    public TextCanvas getCanvas() {
        return canvas;
    }
    
    public int getHeight() {
        return canvas.numLines() - 1; //XXX: not sure if this is right...
    }
    
    public void print(TextCanvas canvas, int linenum) {
        throw new UnsupportedOperationException();
    }
    
    public void render() {
        if (model.getTopLabel()) {
            drawPlayerLabels();
        }
        drawPlayerLines = true;
        canvas.newline();
        if (model.getLinePadding() == 0) {
            // always start with empty line
            canvas.newline();
        }
        
        renderEvents();
        
        drawPlayerLines = false;
        if (model.getBottomLabel()) {
            drawPlayerLabels();
        }
    }
    
    private void drawPlayerLabels() {
        HGroup hgroup = new HGroup();
        for (Player p : players) {
            Label label = new Label(p.getName(), p);
            label.setAnchorPos(XPosition.CENTER);
            label.setLabelPos(XPosition.CENTER);
            label.setTextAlignment(Alignment.CENTER);
            hgroup.addEvent(label);
        }
        HGroupTextRenderer hgtr = new HGroupTextRenderer(hgroup);
        hgtr.render();
        hgtr.print(canvas, canvas.numLines() - 1);
    }
    
    // invoked from TextCanvas
    void newline(TextLine line) {
        if (drawPlayerLines) {
            for (int i = 0; i < players.length; i++) {
                line.write(players[i].getLineChar(), players[i].getColumn());
            }
        }
    }
    
    public void renderEvents() {
        for (Event ev : model.getEvents()) {
            linePadding();
            ev.accept(this);
            canvas.newline();
        }
    }
    
    private void linePadding() {
        logger.debug("linePadding: " + model.getLinePadding());
        for (int i = 0; i < model.getLinePadding(); i++) {
            canvas.newline();
        }
    }
    
    public void visit(Message msg) {
        MessageTextRenderer mtr = new MessageTextRenderer(msg);
        mtr.render();
        mtr.print(canvas, canvas.numLines() - 1);
    }
    
    public void visit(Label label) {
        LabelTextRenderer ltr = new LabelTextRenderer(label, -1);
        ltr.render();
        ltr.print(canvas, canvas.numLines() - 1);
    }
    
    public void visit(HGroup hgroup) {
        HGroupTextRenderer hgtr = new HGroupTextRenderer(hgroup);
        hgtr.render();
        hgtr.print(canvas, canvas.numLines() - 1);
    }
}
